#include "ttClient.h"
#include "myUtil.h"
#include "ttPack.h"
#include "autoLock.h"
#include "Me.h"
#include "ttClientPrxMgr.h"
#include "ttMsgMap.h"
#include "ttClientProxyOnClient.h"

ttClient::ttClient()
{}


ttClient::~ttClient()
{}

int ttClient::setIPandPortandName(char *ip, int port, WCHAR *name)
{
	strcpy(m_hostIP, ip);
	m_hostPort = port;
    setName(name);
	return 0;
}

int 
ttClient::ttConnect()
{
	m_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == m_s){
		myUtil::testoutput("INVALID_SOCKET");
		return -1;
	}

	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.S_un.S_addr = inet_addr(m_hostIP);
	servAddr.sin_port = htons(m_hostPort);

	if (SOCKET_ERROR == connect(m_s, (SOCKADDR *)&servAddr, sizeof(servAddr))){
		myUtil::testoutput("Connect Failed! %d\n",WSAGetLastError());
		return -1;
	}

    myUtil::myCreateThread(ttClient::recvWorkThread, this);
	myUtil::myCreateThread(ttClient::sendWorkThread, this);

	return 0;
}

int
ttClient::move(float speed)
{
	pttpack ppack = new ttpack;
	ppack->flag = ttpackflag::TP_CLIENTMOVE;
	ppack->x = this->getX();
	ppack->y = this->getY();
	ppack->btnUDDirection = this->getBtnUDDir();
	ppack->btnLRDirection = this->getBtnLRDir();
	ppack->direction = this->getDirection();
    ppack->bUDMoving = this->getUDMoving();
    ppack->bLRMoving = this->getLRMoving();
	ppack->speed = speed;
	{	
		autoLock lock(ttClient::Get()->m_cs);
		this->push_back(ppack);
	}
	__super::move(speed);
	return 0;
}

int
ttClient::speak(WCHAR *sentence)
{
	pttpack ppack = new ttpack;
	ppack->flag = ttpackflag::TP_CLIENTSPEAK;
	ppack->id = m_id;
	wsprintf(ppack->sentence, L"%s", sentence);
	wsprintf(ppack->name, m_name);
	{
		autoLock lock(this->m_cs);
		this->push_back(ppack);
	}
	return 0;
}

DWORD WINAPI
ttClient::recvWorkThread(LPVOID pParam)
{
	myUtil::testoutput("client recvWork");
	IttClient* pClient = (IttClient*)pParam;
	while(bRunning){
		pttpack ppack = new ttpack;
        myUtil::Recved(pClient->getS(), (char *)ppack, sizeof(ttpack));

		autoLock lock(pClient->m_cs);
		pClient->push_back(ppack);
	}
	return 0;
}

DWORD WINAPI
ttClient::sendWorkThread(LPVOID pParam)
{
	IttClient* pClient = (IttClient*)pParam;
	ttpack tpack;
	tpack.flag = ttpackflag::TP_NAME;
	wsprintf(tpack.name, L"%s", pClient->getName());
	tpack.x = pClient->getX();
	tpack.y = pClient->getY();
    myUtil::Sended(pClient->getS(), (char *)&tpack, sizeof(ttpack));
	while (bRunning){
		pttpack ppack = NULL;
		{
			autoLock lock(pClient->m_cs);
			if (!pClient->isEmpty()){
				ppack = pClient->getfront();
			}
		}
		if (NULL != ppack){
			answer(pClient, ppack);
		}
	}
	return 0;
}

int
ttClient::answer(IttClient *pClient, pttpack ppack)
{
	switch(ppack->flag)
	{
	case ttpackflag::TP_ID:
		{
			myUtil::testoutput("TP_ID : %u", ppack->id);
			pClient->setID(ppack->id);

			ppack->flag = ttpackflag::TP_GETALL;
			myUtil::Sended(pClient->getS(), (char *)ppack, sizeof(ttpack));
			break;
		}
	case ttpackflag::TP_GETALL:
		{
			if (ppack->id != Me->getID()){
				myUtil::testoutput("TP_GETALL : %u", ppack->id);
				autoLock lock(ttClientPrxMgr::Get()->m_cs);
				IttClient* pPrx = new ttClientProxyOnClient;
				pPrx->setID(ppack->id);
				pPrx->setName(ppack->name);
				pPrx->setXY(ppack->x, ppack->y);
				pPrx->setBtnUDDir(ppack->btnUDDirection);
				pPrx->setBtnLRDir(ppack->btnLRDirection);
				pPrx->setDirection(ppack->direction);
				pPrx->setUDMoving(ppack->bUDMoving);
				pPrx->setLRMoving(ppack->bLRMoving);
				ttClientPrxMgr::Get()->push_back(pPrx);
			}
			break;
		}
	case ttpackflag::TP_CLIENTMOVE:
		{
			myUtil::Sended(pClient->getS(), (char *)ppack, sizeof(ttpack));
			break;
		}
	case ttpackflag::TP_CLIENTPRXMOVE:
		{
			autoLock lock(ttClientPrxMgr::Get()->m_cs);
			for (ttClientPrxMgr::THISLIST::iterator iter = ttClientPrxMgr::Get()->getList().begin(); iter != ttClientPrxMgr::Get()->getList().end(); ++ iter){
				if (ppack->id == (*iter)->getID()){
					(*iter)->setXY(ppack->x, ppack->y);
					(*iter)->setBtnUDDir(ppack->btnUDDirection);
					(*iter)->setBtnLRDir(ppack->btnLRDirection);
					(*iter)->setDirection(ppack->direction);
					(*iter)->setUDMoving(ppack->bUDMoving);
					(*iter)->setLRMoving(ppack->bLRMoving);
					(*iter)->move(ppack->speed);
					break;
				}
			}
			break;
		}
	case ttpackflag::TP_CLIENTPRXSPEAK:
		{
			if (ppack->id != pClient->getID()){
				ttMsgMap::_msgloopvar::pmsg pMsg = new ttMsgMap::_msgloopvar::msg;
				wsprintf(pMsg->buf, L"%s : %s", ppack->name, ppack->sentence);
				{
					autoLock lock(ttMsgMap::Get()->m_msglpvar.m_csMsgList);
					ttMsgMap::Get()->m_msglpvar.m_msglist.push_back(pMsg);
				}
			}
			break;
		}
	case ttpackflag::TP_CLIENTSPEAK:
		{
			myUtil::Sended(pClient->getS(), (char *)ppack, sizeof(ttpack));
			break;
		}
	}
	delete ppack;
	return 0;
}